#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;
#define BUFFER_SIZE 20
/*定义锁*/
pthread_mutex_t g_mutex;

/*定义条件变量*/
pthread_cond_t notEmpty;
/*定义条件变量*/
pthread_cond_t notFull;

/*链表节点*/
struct Node
{
    /*数据域*/
    int data;
    /*指针域*/
    Node *next;
};

/*链表的头节点*/
Node *g_head = NULL;

/*链表节点数量*/
int g_size = 0;

/*生产者线程*/
void *thread_produce(void *arg)
{
    /*线程分离*/
    pthread_detach(pthread_self());

    // /*休眠10s*/
    // sleep(5);

    /*编号*/
    int number = 1;

    while (1)
    {
        /*加锁*/
        pthread_mutex_lock(&g_mutex);

        while (g_size == BUFFER_SIZE)
        {
            pthread_cond_wait(&notFull, &g_mutex);
        }

        Node *newNode = new Node;
        newNode->data = number;
        newNode->next = g_head;
        g_head = newNode;

        /*链表个数++*/
        g_size++;
        /*解锁*/
        pthread_mutex_unlock(&g_mutex);

        printf("produce: %ld produce %d,剩余%d张饼\n", pthread_self(), number, g_size);
        number++;

        /*通知食客开吃*/
        pthread_cond_signal(&notEmpty);
        usleep(500000);
    }
    /*线程退出*/
    pthread_exit(NULL);
}

/*创建消费者线程*/
void *thread_consumer(void *arg)
{
    sleep(20);
    while (1)
    {
        /*加锁*/
        pthread_mutex_lock(&g_mutex);

        while (g_head == NULL)
        {
            /*等待条件变量*/
            pthread_cond_wait(&notEmpty, &g_mutex);
        }

        /*消费*/
        Node *consumNode = g_head;

        g_head = g_head->next;

        /*链表的个数--*/
        g_size--;
        /*锁的粒度*/
        /*解锁*/
        pthread_mutex_unlock(&g_mutex);

        /*开吃*/
        printf("threadId=%ld \teat %d,还剩多少%d张饼\n", pthread_self(), consumNode->data, g_size);
        if (consumNode != NULL)
        {
            delete consumNode;
            consumNode = NULL;
        }

        sleep(2);

        /*发信号*/
        pthread_cond_signal(&notFull);
    }
}

int main(int argc, char const *argv[])
{
    /*创建生产者线程*/
    pthread_t tid1;
    int ret = pthread_create(&tid1, NULL, thread_produce, NULL);
    if (ret != 0)
    {
        cout << "thread create error." << endl;
        _exit(-1);
    }

    /*创建消费者线程*/
    pthread_t tid2;
    ret = pthread_create(&tid2, NULL, thread_consumer, NULL);
    if (ret != 0)
    {
        cout << "thread create error." << endl;
        _exit(-1);
    }

    /*创建消费者线程*/
    pthread_t tid3;
    ret = pthread_create(&tid3, NULL, thread_consumer, NULL);
    if (ret != 0)
    {
        cout << "thread create error." << endl;
        _exit(-1);
    }

    int cnt = 1000;
    while (cnt--)
    {
        sleep(1);
    }

    return 0;
}
